from nltk.corpus import verbnet 

'''
Created on Mar 29, 2014

@author: dan
'''

class verbframes(object):
    '''
    classdocs
    '''
    
    syntaxes = list()
    themroles = list()
    
    class framesyntax():
        HyperRestr = { 'concrete'     : ['physical_entity.n.01'],
                       'abstract'     : ['abstraction.n.06'],
                       'communication': ['communication.n.02'],
                       'body_part'    : ['body_part.n.01'],
                       'animate'      : ['causal_agent.n.01', 'living_thing.n.01'],
                       'pointy'       : ['physical_entity.n.01'],
                       'refl'         : ['physical_entity.n.01'],
                       'solid'        : ['physical_entity.n.01'],
                       'organization' : ['group.n.01'],
                       'region'       : ['region.n.01'],
                       'location'     : ['location.n.01', 'location.n.03'],
                       'animal'       : ['animal.n.01'],
                       'force'        : ['entity.n.01'],
                       
                       'Instrument'   : ["instrumentality.n.03", "act.n.02", 'communication.n.02', 'body_part.n.01'],
                       'Theme'        : ['entity.n.01'],
                       'Actor'        : ['causal_agent.n.01'],
                       'Patient'      : ['entity.n.01'],
                       'Recipient'    : ['entity.n.01'],
                       'Oblique'      : ['entity.n.01'],
                       'Location'     : ['location.n.01', 'location.n.03'],
                       'Destination'  : ['entity.n.01'],
                       'Experiencer'  : ['entity.n.01'],
                       'Source'       : ['entity.n.01'],
                       'Beneficiary'  : ['entity.n.01'],
                       'Agent'        : ['entity.n.01'],
                        }

        DictRestr = {  'concrete'    : 'return false',
                       'abstract'     : 'return false',
                       'communication': 'return false',
                       'body_part'    : 'return false',
                       'animate'      : 'return false',
                       'pointy'       : 'sharp',
                       'refl'         : 'return false',
                       'solid'        : 'return false',
                       'organization' : 'return false',
                       'region'       : 'return false',
                       'location'     : 'return false',
                       'animal'       : 'return false',
                       'force'        : 'return false',
                     
                       'Instrument'   : 'used ',
                       'Theme'        : 'return false',
                       'Actor'        : 'return false',
                       'Patient'      : 'return false',
                       'Oblique'      : 'return false',
                       'Recipient'    : 'return false',
                       'Location'     : 'return false',
                       'Destination'  : 'return false',
                       'Experiencer'  : 'return false',
                       'Source'       : 'return false',
                       'Beneficiary'  : 'return false',
                       'Agent'        : 'return false',
                       }
    
        def __init__(self, syntax):
            self.sentence = []
            for element in syntax:
                if element.tag == 'NP':
                    newNP = self.syntaxNP(element)
                    self.sentence.append( newNP )
                elif element.tag == 'VERB':
                    newVerb = self.syntaxVerb()
                    self.sentence.append( newVerb )
                    print 'VERB'
                elif element.tag == 'PREP':
                    newPrep = self.syntaxPrep( element.get('value') )
                    self.sentence.append( newPrep )
                    print newPrep.values, len(self.sentence)
                elif element.tag == 'LEX':
                    newLex = self.syntaxLex( element.get('value') )
                    self.sentence.append( newLex )
                    print newLex.value, len(self.sentence)
                else:
                    print "UNRECOGNIZED FRAME SYNTAX ELEMENT", element.tag
                    print "WITH KEYS: ", element.keys()
                    print "AND CHILDREN: ", element.getchildren()
        
        class syntaxNP():
            '''
            '''
                        
            def __init__(self, tree):
                self.role = tree.get('value')
                self.require = list()
                self.refuse = list()
                if tree.find('SYNRESTRS'):
                    for restriction in tree.find('SYNRESTRS'):
                        if restriction.get('Value') == '+':
                            self.require.append( restriction.get('type') )
                            print "+", restriction.get('type')
                        else:
                            self.refuse.append( restriction.get('type') )
                            print "-", restriction.get('type')
                print self.role
    
        class syntaxVerb():
            '''
            '''
            def __init__(self):
                pass
        
        class syntaxPrep(object):
            '''
            '''
            def __init__( self, string ):
                self.values = string.split(' ')
            
        class syntaxLex():
            def __init__( self, string ):
                self.value = string
    
    class themrole():
        def __init__(self, tree):
            self.roletype = tree.get('type')
            self.require = list()
            self.refuse = list()
            selrestrs = tree.find('SELRESTRS') 
            self.logic = selrestrs.get('logic')
            for restriction in selrestrs:
                if restriction.get('Value') == '+':
                    self.require.append( restriction.get('type') )
                else:
                    self.refuse.append( restriction.get('type') )
        def match(self, nounsense):
            '''check against themrole'''                
            if not nounsense.ingloss( verbframes.framesyntax.DictRestr[self.roletype] ) and \
               not nounsense.inheritsfrom( verbframes.framesyntax.HyperRestr[self.roletype] ):
                print "failed themrole match"
                return False
            
            '''check against selectional restrictions'''
            
            if self.logic == 'and':
                for requirement in self.require:
                    if not nounsense.ingloss( verbframes.framesyntax.DictRestr[requirement] ) and \
                       not nounsense.inheritsfrom( verbframes.framesyntax.HyperRestr[requirement] ):
                        print "failed requirement", requirement, 'and' 
                        return False
                for restriction in self.refuse:
                    if nounsense.ingloss( verbframes.framesyntax.DictRestr[restriction] ) or \
                       nounsense.inheritsfrom( verbframes.framesyntax.HyperRestr[restriction] ):
                        print "failed restriction", restriction, 'and'
                        return False
    
            if self.logic == 'or':
                match = False
                for requirement in self.require:
                    if nounsense.ingloss( verbframes.framesyntax.DictRestr[requirement] ) or \
                       nounsense.inheritsfrom( verbframes.framesyntax.HyperRestr[requirement] ):
                        match = True
                if match == False:
                    print "failed or" 
                    return False
            return True
    
    def __init__(self, vntree):
        '''
        Constructor
        Takes in an elementtree generated by verbnet.vnclass()
        '''
        self.themroles = dict()
        
        
        '''if this is a subclass, APPARENTLY I have to get the superclass
           thematic role selectional restrictions MANUALLY.'''
        if vntree.get('ID').count('-') > 1: #two hypens implies subclass
            #grab the part before the second hypen
            superclassname = vntree.get('ID')[0:vntree.get('ID').rindex('-')]
            superclass = verbnet.vnclass( superclassname )
            '''from the superclass, get thematic roles and their related restrictions'''
            roles = superclass.find("THEMROLES")
            for role in roles:
                newrole = self.themrole( role )
                self.themroles[newrole.roletype] = newrole
            
        '''get the thematic roles and their related restrictions'''
        roles = vntree.find("THEMROLES")
        for role in roles:
            newrole = self.themrole( role )
            self.themroles[newrole.roletype] = newrole
            '''parent roles are overwritten with new restrictions'''
        for tr in self.themroles:
            print tr
            print "Require: ", self.themroles[tr].require
            print "Refuse: ", self.themroles[tr].refuse
        
        '''get the frame syntaxes'''
        frames = vntree.find("FRAMES")
        for frame in frames:
            syntax = self.framesyntax( frame.find("SYNTAX") )
            self.syntaxes.append(syntax)
            
